import numpy as np
import pandas as pd
import holoviews as hv
hv.extension('bokeh', 'matplotlib')
import re
import sys
import itertools
df = pd.read_csv('hackaturing_3.dsv', index_col=0, dtype={'cid':object})
df.head()
df['valor_glosa'] = df['valor_cobrado'] - df['valor_pago']
print('Total de glosas: R$ {:,.0f}'.format(df['valor_glosa'].sum()))
%%opts Histogram [width=700, show_grid=True]
glosas = np.array(df[df['valor_glosa']>0]['valor_glosa'])
densities, values = np.histogram(glosas, bins=100, density=True, weights=glosas)
cumulative = np.cumsum(densities) * (values[1]-values[0])
hv.Histogram((cumulative, values), label='Distribuição das glosas em R$').redim(
x={'label':'Valor de Cada Glosa Individual'},
Frequency={'range':(0,1), 'label':'% do Total de Glosas'}
)
%%opts Histogram [width=700, show_grid=True, tools=['hover']]
glosas = np.array(df[df['valor_glosa']>0]['valor_glosa'])
densities, values = np.histogram(glosas, bins=100000, density=True, weights=glosas)
cumulative = np.cumsum(densities) * (values[1]-values[0])
hv.Histogram((cumulative, values), label='Distribuição das glosas em R$ (detalhe das glosas menores)').redim(
x={'range':(0,10), 'label':'Valor de Cada Glosa Individual'},
Frequency={'range':(0,0.1), 'label':'% do Total de Glosas'}
)
%%opts Histogram [width=700, show_grid=True, tools=['hover']]
glosas = np.array(df[df['valor_glosa']>0]['valor_glosa'])
densities, values = np.histogram(glosas, bins=100000, density=True)
cumulative = np.cumsum(densities) * (values[1]-values[0])
hv.Histogram((cumulative, values), label='Distribuição das glosas em número (detalhe das glosas menores)').redim(
x={'range':(0,10), 'label':'Valor de Cada Glosa Individual'},
Frequency={'range':(0,1), 'label':'% do # Total de Glosas'}
)
As glosas de até 3 reais representam 55% do número total de glosas mas, somente, 1.3% do valor total.
Então, faz sentido abrir mão de todo o processamento de glosas menores?
50% a menos do trabalho por um custo de 1.3%, mas que vai direto no bottom-line?
Se sim, talvez, então, valha a mesma conta para glosas de valores indivudiais maiores também... a se estudar com as operadoras
%%opts Table [width=2000]
hv.Table(df[(df['valor_glosa']<1)&(df['valor_glosa']>0)][[
'sexo', 'data_nascimento', 'cid', 'data_entrada', 'tipo_guia', 'tipo_item', 'carater_atendimento', 'servico',
'descricao_despesa', 'quantidade', 'valor_item', 'valor_cobrado', 'valor_pago', 'ano_mes', 'age', 'valor_glosa'
]])
valor glosado > R$ 0.01
valor glosado > 1% do valor cobrado
df['glosa'] = (df['valor_glosa']>0.01) & (df['valor_glosa']>0.01*df['valor_cobrado']).astype(int)
df = df.drop(df[df['valor_glosa']<0].index)
df[df['glosa']==True]['valor_glosa'].sum() / df['valor_glosa'].sum()
df[df['glosa']].shape[0], df[df['valor_glosa']>0].shape[0], df.shape[0]
df['data_item'] = pd.to_datetime(df['data_item'])
df['data_entrada'] = pd.to_datetime(df['data_entrada'])
df['data_saida'] = pd.to_datetime(df['data_saida'])
df['data_nascimento'] = pd.to_datetime(df['data_nascimento'])
df['dias_tratamento'] = (df['data_saida'] - df['data_entrada']).dt.days
df['weekday_entrada'] = df['data_entrada'].dt.dayofweek
df['weekday_item'] = df['data_item'].dt.dayofweek
df['mes'] = df['data_item'].dt.month
%%opts Bars [height=300 width=350]
hv.Bars(df.groupby('sexo')['glosa'].mean()) + hv.Bars(df.groupby('tipo_guia')['glosa'].mean())
%%opts Bars [height=300 width=350]
hv.Bars(df.groupby('weekday_entrada')['glosa'].mean()) + hv.Bars(df.groupby('weekday_item')['glosa'].mean())
%%opts Bars [height=300 width=350 xrotation=30]
hv.Bars(df.groupby('tipo_item')['glosa'].mean())
%%opts Bars [height=300 width=350 xrotation=30]
hv.Bars(df.groupby('carater_atendimento')['glosa'].mean())
%%opts Bars [height=300 width=400 xrotation=30]
hv.Bars(df.groupby('mes')['glosa'].mean())
Dando uma olhada nos dados por ano_mes, há algum comportamento estranho nos meses antes de 02/2017...
Possivelmente devido ao slicing do dataset.
Idealmente esse estudo deveria ser refeito com um dataset mais completo, e com o timeframe maior.
%%opts Bars [height=300 width=450 xrotation=30]
hv.Bars(df.groupby('prestador')['glosa'].mean())
Ainda daria para tentar pelo beneficiario final e pela operadora.
Mas, devido a alta cardinalidade do beneficiario nesse dataset, possivelmente, não trará algum resultado significativo (a não ser que overfit)